package cn.ug.util;

import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

import static cn.ug.util.ConstantUtil.NORMAL_DATE_FORMAT;
import static cn.ug.util.ConstantUtil.MINUS;
import static cn.ug.util.ConstantUtil.WAVE;

/**
 * 常用函数
 * @author kaiwotech
 */
public class UF extends UserFunction{
    public static final String INVITE_CODE_PREFIX = "Yj";

    private static Calendar getCalendarFormYear(int year){
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        cal.set(Calendar.YEAR, year);
        return cal;
    }

    public static List<String> getWeekInterval(String startDate, String endDate) {
        if (StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
            return null;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
        List<String> weeks = new ArrayList<String>();
        try {
            Date endDatetime = dateFormat.parse(endDate);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(endDatetime);
            int week = calendar.get(Calendar.DAY_OF_WEEK);
            if (week == 1) {
                calendar.add(Calendar.DAY_OF_YEAR, -1);
            }
            Set<String> info = new HashSet<String>();
            SimpleDateFormat weekFormat = new SimpleDateFormat("yyyy-ww");
            for(;;) {
                String value = weekFormat.format(calendar.getTime());
                if (!info.contains(value)) {
                    info.add(value);
                    String[] arrs = StringUtils.split(value, MINUS);
                    weeks.add(getWeekInterval(Integer.parseInt(arrs[0]), Integer.parseInt(arrs[1])));
                }
                if (StringUtils.startsWith(startDate, dateFormat.format(calendar.getTime()))) {
                    break;
                }
                calendar.add(Calendar.DAY_OF_YEAR, -1);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        List<String> result = new ArrayList<String>();
        if (weeks != null && weeks.size() > 0) {
            for (int i = 0; i < weeks.size(); i++) {
                if (i == 0) {
                    result.add(StringUtils.split(weeks.get(i), WAVE)[0] + WAVE + endDate);
                } else if (i == (weeks.size() - 1)) {
                    result.add(startDate+WAVE+StringUtils.split(weeks.get(i), WAVE)[1]);
                } else {
                    result.add(weeks.get(i));
                }
            }
        }
        return result;
    }

    /**
     *  根据年和本年的周数获取该周的时间段
     * @param year
     * @param weekNO
     * @return
     */
    public static String getWeekInterval(int year, int weekNO) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
        Calendar startCalendar = getCalendarFormYear(year);
        startCalendar.set(Calendar.WEEK_OF_YEAR, weekNO);
        String stardDate = dateFormat.format(startCalendar.getTime());

        Calendar endCalendar = getCalendarFormYear(year);
        endCalendar.set(Calendar.WEEK_OF_YEAR, weekNO);
        endCalendar.add(Calendar.DAY_OF_WEEK, 6);
        String endDate = dateFormat.format(endCalendar.getTime());
        return stardDate + "～" + endDate;
    }

    /**
     * double转成字符串
     * @param value     double
     * @param pattern   格式 #.## （1.234 -> 1.23 | 1.1 -> 1.1） #。00 （1.234 -> 1.234 | 1.1 -> 1.10）
     * @return          格式化后的字符串
     */
    public static String toString(double value, String pattern) {
        if(StringUtils.isBlank(pattern)) {
            pattern = "#.##";
        }
        DecimalFormat df = new DecimalFormat(pattern);

        return df.format(value);
    }

    public static String getInviteCode() {
        String offset = String.valueOf(ThreadLocalRandom.current().nextInt(0, 1000000));
        if (StringUtils.length(offset) < 6) {
            offset = StringUtils.leftPad(offset, 6, '0');
        }
        return INVITE_CODE_PREFIX+offset;
    }

    /**
     * double转成字符串, 保留小数点后两位，不足两位补0
     * @param value     double
     * @return          格式化后的字符串
     */
    public static String toStringWith2P(double value) {
        return toString(value, "#.00");
    }

    /**
     * 通过反射获取Bean中所有属性和属性值
     * @param o Bean
     * @return  属性和属性值
     */
    public static Map<String, String> getFieldMap (Object o) {
        Map<String, String> fieldMap = new HashMap<>();

        try {
            Field[] fields = o.getClass().getDeclaredFields();
            Field.setAccessible(fields, true);
            for (Field field : fields) {
                Object obj = field.get(o);

                if(obj instanceof String || obj instanceof Integer || obj instanceof Double) {
                    fieldMap.put(field.getName(), field.get(o).toString());
                    continue;
                }
            }
            if(null != o.getClass().getGenericSuperclass()) {
                // 如果有父类
                fields = o.getClass().getSuperclass().getDeclaredFields();
                Field.setAccessible(fields, true);
                for (Field field : fields) {
                    Object obj = field.get(o);

                    if(obj instanceof String || obj instanceof Integer || obj instanceof Double) {
                        fieldMap.put(field.getName(), field.get(o).toString());
                        continue;
                    }
                }
            }
        } catch (Exception e) {
        }

        return fieldMap;
    }
}